SSM セッションマネージャーでサーバー上の操作ログを取得
こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。
AWS 上の EC2 に対してリモートでメンテナンスする際に
監査の要件でサーバー上の操作ログを取得しければならないシステムは数多いと思います。
今回はセッションマネージャーを使って
サーバーメンテナンス操作ログを徹底的に記録してみます。
前提
以下のような前提を置きました。
- リモートからのメンテナンスは必ず踏み台サーバーを経由する
- 踏み台サーバーへはセッションマネージャー経由でログインする
- SSH ポートは開放しない
- 踏み台サーバーへのアクセス許可は IAM で管理
- 踏み台サーバーは Amazon Linux 2
- ログインはメール通知
- ログイン後の操作ログは S3 へ保管
準備
リモートメンテナンスを行うクライアント PC に
AWS CLI と Session Manager Plugin をインストールします。
インストール方法は最新情報を確認し、最新バージョンをインストールするようお願いします。
Windows に AWS CLI をインストールする
Windows に Session Manager Plugin をインストールする
macOS に AWS CLI をインストールする
macOS で Session Manager Plugin をインストールおよびアンインストールする
AWS CLI
インストールが完了したら CLI の初期設定を行います。
$ aws configure AWS Access Key ID []: ご自身の IAM ユーザーのアクセスキーを入力 AWS Secret Access Key []: ご自身の IAM ユーザーのシークレットアクセスキーを入力 Default region name []: ap-northeast-1 と入力 Default output format []: そのままエンター
環境設定
SNS
セッションマネージャー経由のログインをメールで通知するための設定を行います。
管理者権限、または、SNS 操作権限を持った IAM ユーザーで以下コマンドを実行します。
※your-topic は任意の名称に置き換えてください。
$ aws sns create-topic --name your-topic --attributes DisplayName=SessionManager { "TopicArn": "arn:aws:sns:ap-northeast-1:123456789012:your-topic" }
TopicArn が結果として出力されるのでメモしておきます。
作成したトピックをサブスクライブします。
※ --topic-arn は上でメモしたものを指定ください。
※ your-mail-address は任意のメールアドレスに置き換えてください。
$ aws sns subscribe --topic-arn arn:aws:sns:ap-northeast-1:123456789012:your-topic --protocol email --notification-endpoint your-mail-address
「AWS Notification - Subscription Confirmation」という件名のメールが届きます。
内容を確認して Confirm してください。
CloudWatch Events
セッションマネージャー経由のログインを通知するために
CloudWatch Events を使います。
管理者権限、または、CloudWatch Events 操作権限を持った IAM ユーザーで以下コマンドを実行します。
$ aws events put-rule --name "StartSession" --event-pattern "{\"source\":[\"aws.ssm\"],\"detail-type\":[\"AWS API Call via CloudTrail\"],\"detail\":{\"eventSource\":[\"ssm.amazonaws.com\"],\"eventName\":[\"StartSession\",\"ResumeSession\"]}}" $ aws events put-targets --rule StartSession --target "Id"="1","Arn"="arn:aws:sns:ap-northeast-1:880749116261:session-notification"
インスタンスプロファイルの作成
踏み台サーバー用のインスタンスプロファイルを作成します。
管理者権限、または、IAM 及び EC2 操作権限を持った IAM ユーザーで以下コマンドを実行します。
ロールの作成
以下の JSON ファイルを作成します。
ファイル名は例で assumerole.json にしています。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": [ "ssm.amazonaws.com", "ec2.amazonaws.com" ] }, "Action": "sts:AssumeRole" } ] }
ロールを作成します。
※ EC2SSMRole は任意のロール名に置き換えてください。
$ aws iam create-role --role-name EC2SSMRole --assume-role-policy-document file://assumerole.json $ aws iam create-instance-profile --instance-profile-name EC2SSMRole $ aws iam add-role-to-instance-profile --role-name EC2SSMRole --instance-profile-name EC2SSMRole
S3アクセス用ポリシーの作成
2020.4.10更新
公開した当時は AmazonEC2RoleforSSM というやや強めのサービスロールを使っていました。このサービスロールは現在では使えません。それに対応するため手順を修正しました。
以下の JSON ファイルを作成します。
ファイル名は例で ssmlogs3.json にしています。
※ファイル内の your-bucketname はご自身のバケット名に置き換えてください。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:PutObject", "s3:GetObject" ], "Resource": "arn:aws:s3:::your-bucketname/*", "Effect": "Allow" }, { "Action": [ "s3:GetBucketLocation", "s3:GetEncryptionConfiguration", "s3:ListBucket", "s3:ListBucketMultipartUploads" ], "Resource": "arn:aws:s3:::your-bucketname", "Effect": "Allow" } ] }
ポリシーを作成します。
※ EC2SSMRole は任意のロール名に置き換えてください。
$ aws iam create-policy --policy-name CustomPolicyssmlogs3 --policy-document file://ssmlogs3.json
上コマンドの標準出力の Arn をコピーします。
作成したポリシーをロールにアタッチします。
※ EC2SSMRole は任意のロール名に置き換えてください。
$ aws iam attach-role-policy --role-name EC2SSMRole --policy-arn 上でコピーしたArn
SSM用ポリシーのアタッチ
作成したロールに AmazonSSMManagedInstanceCore をいう SSM 用ポリシーをアタッチします。
$ aws iam attach-role-policy --role-name EC2SSMRole --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
EC2 インスタンスにインスタンスプロファイルをアタッチ
ロールを EC2 にアタッチします。
※ your-instance-id は対象の EC2 インスタンスに置き換えてください。
$ aws ec2 associate-iam-instance-profile --iam-instance-profile Name=EC2SSMRole --instance-id your-instance-id
S3 バケット
操作ログをテキストファイルで保管する S3 バケットを作成します。
管理者権限、または、S3 操作権限を持った IAM ユーザーで以下コマンドを実行します。
※ your-bucket-name は任意の名称に置き換えてください。
$ aws s3 mb s3://your-bucket-name $ aws s3api put-bucket-encryption --bucket your-bucket-name --server-side-encryption-configuration "{\"Rules\":[{\"ApplyServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"AES256\"}}]}" $ aws s3api put-public-access-block --bucket your-bucket-name --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
セッションマネージャー
この手順はマネジメントコンソールから行います。
セッションマネージャー を開きます。
設定 タブを開き 編集 をクリックします。
今回は以下のように設定します。
項目 | 値 |
---|---|
Enable Run As support for Linux instances | チェックをオフ |
Key Management Service (KMS) | チェックをオフ |
S3 バケット | チェックをオン |
ログデータの暗号化 | チェックをオン |
リストからバケット名を選択 | 前の手順で作成したバケットを選択 |
S3 キープレフィックス - オプション | sessionmanager |
CloudWatch ログ | チェックをオフ |
リモートメンテナンスの開始
準備が整いました。
踏み台サーバーへのログイン許可は IAM で制御します。
セッションマネージャー経由のログインを許可する IAM ユーザー/グループに
以下の IAM ポリシーをアタッチします。
IAM ポリシーの作成
以下の JSON ファイルを作成します。
ファイル名は例で session.json にしています。
※ your-account-id はご自身のアカウントに置き換えてください。
※ your-instance-id はご自身の EC2 インスタンス (踏み台) に置き換えてください。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "0", "Effect": "Allow", "Action": "ssm:StartSession", "Resource": "arn:aws:ec2:ap-northeast-1:your-accont-id:instance/your-instance-id" } ] }
$ aws iam create-policy --policy-name ssm-session-policy --policy-document file://session.json
作成したポリシーはセッションマネージャーを許可する IAM ユーザー/グループにアタッチしてください。
接続
それでは踏み台サーバーへログインします。
以下のコマンドを実行します。
※ your-instance-id はご自身の EC2 インスタンス (踏み台) に置き換えてください。
$ aws --profile ssmuser ssm start-session --target your-instance-id
試しに適当なコマンドを実行してみます。
Starting session with SessionId: ssmuser-05b997125a8bfd115 sh-4.2$ sh-4.2$ sh-4.2$ date Sat Aug 24 06:58:39 UTC 2019 sh-4.2$ sh-4.2$ sh-4.2$ date Sat Aug 24 06:58:40 UTC 2019 sh-4.2$ sh-4.2$ sh-4.2$ sh-4.2$ exit
メール通知
ログインをメールで通知することにしていました。
受信ボックスを見てみます。
通知が届いています。
S3 バケット内
作成した S3 バケットにテキストファイルが作成されています。
Script started on 2019-08-24 06:58:51+0000 [?1034hsh-4.2# /usr/bin/ssm-session-logger /var/lib/amazon/ssm/i-xxxxxxxxx/sess ion/orchestration/ssmuser-05b997125a8bfd115/Standard_Stream/ipcTempFile.log fals e Error occurred fetching the seelog config file path: open /etc/amazon/ssm/seelog.xml: no such file or directory Initializing new seelog logger New Seelog Logger Creation Complete [?1034hsh-4.2$ [Ksh-4.2$ sh-4.2$ sh-4.2$ date Sat Aug 24 06:58:39 UTC 2019 sh-4.2$ sh-4.2$ sh-4.2$ date Sat Aug 24 06:58:40 UTC 2019 sh-4.2$ sh-4.2$ sh-4.2$ sh-4.2$ exit exit sh-4.2# exit exit Script done on 2019-08-24 06:59:56+0000
まとめ
踏み台サーバー経由のリモートメンテナンスという観点では
強めの統制をきかせることが出来るのはないでしょうか。
SSH ポートをセキュリティグループで空けなくてよく
接続権限は IAM 管理可能ということで、運用コストは減らせるかもしれません。
ぜひご活用ください。
参考
Amazon CloudWatch Logs を使用して CloudTrail のログファイルをモニタリングする
以上、吉井 亮 がお届けしました。